home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
mac
/
files
/
t_sys5
/
92052tar.gz
/
920528.tar
/
ax25subr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-29
|
3KB
|
148 lines
/* @(#) $Header: ax25subr.c,v 1.7 91/03/28 19:39:12 deyke Exp $ */
/* Low level AX.25 routines:
* callsign conversion
* control block management
*
* Copyright 1991 Phil Karn, KA9Q
*/
#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "timer.h"
#include "ax25.h"
#include "lapb.h"
#include <ctype.h>
/*
* setcall - convert callsign plus substation ID of the form
* "KA9Q-0" to AX.25 (shifted) address format
* Address extension bit is left clear
* Return -1 on error, 0 if OK
*/
int
setcall(out,call)
char *out;
char *call;
{
int csize;
unsigned ssid;
register int i;
register char *dp;
char c;
if(out == NULLCHAR || call == NULLCHAR || *call == '\0')
return -1;
/* Find dash, if any, separating callsign from ssid
* Then compute length of callsign field and make sure
* it isn't excessive
*/
dp = strchr(call,'-');
if(dp == NULLCHAR)
csize = strlen(call);
else
csize = dp - call;
if(csize > ALEN)
return -1;
/* Now find and convert ssid, if any */
if(dp != NULLCHAR){
dp++; /* skip dash */
ssid = atoi(dp);
if(ssid > 15)
return -1;
} else
ssid = 0;
/* Copy upper-case callsign, left shifted one bit */
for(i=0;i<csize;i++){
c = *call++;
if(islower(c))
c = toupper(c);
*out++ = c << 1;
}
/* Pad with shifted spaces if necessary */
for(;i<ALEN;i++)
*out++ = ' ' << 1;
/* Insert substation ID field and set reserved bits */
*out = 0x60 | (ssid << 1);
return 0;
}
int
addreq(a,b)
register char *a,*b;
{
if (*a++ != *b++) return 0;
if (*a++ != *b++) return 0;
if (*a++ != *b++) return 0;
if (*a++ != *b++) return 0;
if (*a++ != *b++) return 0;
if (*a++ != *b++) return 0;
return (*a & SSID) == (*b & SSID);
}
/* Return iface pointer if 'addr' belongs to one of our interfaces,
* NULLIF otherwise.
*/
struct iface *
ismyax25addr(addr)
char *addr;
{
register struct iface *ifp;
for (ifp = Ifaces; ifp; ifp = ifp->next)
if (ifp->output == ax_output && addreq(ifp->hwaddr, addr))
break;
return ifp;
}
void
addrcp(to,from)
register char *to,*from;
{
*to++ = *from++;
*to++ = *from++;
*to++ = *from++;
*to++ = *from++;
*to++ = *from++;
*to++ = *from++;
*to = (*from & SSID) | 0x60;
}
/* Convert encoded AX.25 address to printable string */
char *
pax25(e,addr)
char *e;
char *addr;
{
register int i;
char c;
char *cp;
cp = e;
for(i=ALEN;i != 0;i--){
c = (*addr++ >> 1) & 0x7f;
if(c != ' ')
*cp++ = c;
}
if((*addr & SSID) != 0)
sprintf(cp,"-%d",(*addr >> 1) & 0xf); /* ssid */
else
*cp = '\0';
return e;
}
/* Figure out the frame type from the control field
* This is done by masking out any sequence numbers and the
* poll/final bit after determining the general class (I/S/U) of the frame
*/
int16
ftype(control)
register int control;
{
if((control & 1) == 0) /* An I-frame is an I-frame... */
return I;
if(control & 2) /* U-frames use all except P/F bit for type */
return (int16)(uchar(control) & ~PF);
else /* S-frames use low order 4 bits for type */
return (int16)(uchar(control) & 0xf);
}